/*
*Copyright 2021-2023 NERCIS
*
*Licensed under the Apache License, Version 2.0 (the "License");
*you may not use this file except in compliance with the License.
*You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*Unless required by applicable law or agreed to in writing, software
*distributed under the License is distributed on an "AS IS" BASIS,
*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*See the License for the specific language governing permissions and
*limitations under the License.
*/

package cn.ac.nercis.pes.community.service;

import cn.ac.nercis.pes.common.constant.manage.EvaluationEntryMode;
import cn.ac.nercis.pes.common.constant.manage.EvaluationPasteMethod;
import cn.ac.nercis.pes.common.utils.DataUtils;
import cn.ac.nercis.pes.model.dto.common.Result;
import cn.ac.nercis.pes.model.dto.manage.AppConfigDTO;
import cn.ac.nercis.pes.repository.dal.manage.ConstantRepository;
import cn.ac.nercis.pes.repository.model.manage.ConstantDO;
import cn.ac.nercis.pes.service.utils.FileManage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Optional;

/**
 * 系统配置服务
 */
@Slf4j
@Service
public class SysConfigService {

    private final static String ROOT_DIR_CONSTANT = "默认存储路径";
    private final static String ENTRY_MODE_CONSTANT = "现场测试录入模式";
    private final static String PASTE_MODE_CONSTANT = "粘贴模式";

    private final static String SCHEME_DOC = "测评方案";
    private final static String REPORT_DOC = "测评报告";
    private final static String ASSET_TEMPLATE = "系统资产";
    private final static String EXPORT_DATA = "导出数据";


    private final ConstantRepository constantRepository;

    @Autowired
    public SysConfigService(ConstantRepository constantRepository) {
        this.constantRepository = constantRepository;
    }

    public AppConfigDTO getConfiguration(){
        return AppConfigDTO.builder()
                .rootPath(getConstant(ROOT_DIR_CONSTANT))
                .entryMode(getEvaluationEntryMode())
                .pasteMethod(getEvaluationPasteMode())
                .build();
    }

    public Result<String> saveConfiguration(AppConfigDTO config) {
        var result = setConstant(ROOT_DIR_CONSTANT, config.getRootPath());
        if(!result.isSuccess()){
            return result;
        }
        return setConstant(ENTRY_MODE_CONSTANT, config.getEntryMode().getValue());
    }

    public EvaluationEntryMode getEvaluationEntryMode() {
        return EvaluationEntryMode.getEntryModeByValue(getConstant(ENTRY_MODE_CONSTANT));
    }

    public EvaluationPasteMethod getEvaluationPasteMode() {
        return EvaluationPasteMethod.getPasteMethodByValue(getConstant(PASTE_MODE_CONSTANT));
    }

    public String getSchemeDocStoragePath() {
        var rootPath = getConstant(ROOT_DIR_CONSTANT);
        var file = FileUtils.getFile(rootPath, SCHEME_DOC);
        try {
            if (StringUtils.isNotBlank(rootPath)) {
                FileManage.createDirectory(file);
            }
        } catch (IOException ex) {
            log.error("创建方案存储路径失败", ex);
        }
        return file.getAbsolutePath();
    }

    public String getReportDocStoragePath() {
        var rootPath = getConstant(ROOT_DIR_CONSTANT);
        var file = FileUtils.getFile(rootPath, REPORT_DOC);
        try {
            if (StringUtils.isNotBlank(rootPath)) {
                FileManage.createDirectory(file);
            }
        } catch (IOException ex) {
            log.error("创建报告存储路径失败", ex);
        }
        return file.getAbsolutePath();
    }


    public String getAssetTemplateStoragePath() {
        var rootPath = getConstant(ROOT_DIR_CONSTANT);
        var file = FileUtils.getFile(rootPath, ASSET_TEMPLATE);
        try {
            if (StringUtils.isNotBlank(rootPath)) {
                FileManage.createDirectory(file);
            }
        } catch (IOException ex) {
            log.error("创建资产模版存储路径失败", ex);
        }
        return file.getAbsolutePath();
    }


    public String getExportDataStoragePath() {
        var rootPath = getConstant(ROOT_DIR_CONSTANT);
        var file = FileUtils.getFile(rootPath, EXPORT_DATA);
        try {
            if (StringUtils.isNotBlank(rootPath)) {
                FileManage.createDirectory(file);
            }
        } catch (IOException ex) {
            log.error("创建导出数据存储路径失败", ex);
        }
        return file.getAbsolutePath();
    }


    private void initConfig(String name,String defaultPath){
        Optional<ConstantDO> schemeDocConfig = DataUtils.findFirst(constantRepository.findByName(name));
        if(schemeDocConfig.isEmpty()){
            setConstant(name,defaultPath);
        }
    }

    private String getConstant(String name){
        return DataUtils.findFirst(this.constantRepository.findByName(name))
                .map(ConstantDO::getValue)
                .orElse(StringUtils.EMPTY);
    }

    private Result<String> setConstant(String name, String value){
        ConstantDO constantDO = DataUtils.findFirst(constantRepository.findByName(name))
                .map(c->{
                    c.setValue(value);
                    return c;
                })
                .orElse(ConstantDO.builder().name(name).value(value).sort(1).build());
        if(StringUtils.isEmpty(constantDO.getId())){
            constantDO.setCreateTime(LocalDateTime.now());
        }else{
            constantDO.setModifyTime(LocalDateTime.now());
        }
        return Optional.of(this.constantRepository.save(constantDO))
                .map(ConstantDO::getId)
                .map(Result::success)
                .orElse(Result.failed());
    }
}